<template>
  <div
    v-if="!initializing"
    class="vc-component"
    :style="currStyle"
    @click="() => eventHandler.trigger('点击事件')"
  >
    <span
      v-if="richText"
      class="vc-text vc-rich-text"
      :style="style"
      v-html="currValue"
    ></span>
    <span
      v-else
      class="vc-text"
      :style="style"
    >{{ currValue }}</span>
  </div>
  <div
    v-else
    v-loading="true"
    element-loading-text=""
    style="min-height: 30px;min-width: 30px; --el-mask-color: transparent;"
    class="vc-component"
    :style="visual.parseStyle(currNode.currStyle)"
  ></div>
</template>

<script setup>
import { ref, onMounted, inject, getCurrentInstance, nextTick, computed, onUnmounted } from 'vue';
import visual from "@/visual/js/visual";
import EventHandler from "@/visual/js/event";
import tool from "@/utils/tool";

const props = defineProps({
  node: Object,
  inputParam: Object
});
const initializing = ref(true);
const currNode = ref(props.node);
const currValue = ref('');
const richText = ref(false);
const eventHandler = new EventHandler(
  inject('eventHandler', Function, true),
  getCurrentInstance(),
  currNode.value
);

const init = async(styleId) => {
  initializing.value = true;
  visual.initStyle(currNode.value, styleId);
  richText.value = currNode.value.currCompStyle['rich'] || false;
  await nextTick(() => initializing.value = false);
};

const loadValue = tool.debounce(async() => {
  initializing.value = true;
  const dataList = (await visual.loadData(currNode.value.compData, eventHandler, getData(), currNode.value)).data || [];
  const compStyle = currNode.value.currCompStyle || {};
  const value = dataList.length > 0 && dataList[0]['内容'] || '';
  if (compStyle['formatter'] === 'template') {
    currValue.value = (compStyle['formatterTemplate'] || '')
      .replace('{value}', value || value === 0 ? value : '');
  } else if (compStyle['formatter'] === 'script') {
    try {
      const args = dataList.length > 0 && dataList[0] || {};
      currValue.value = new Function('value', 'args', 'return ' + compStyle['formatterScript'])(value, args);
    } catch (e) {
      console.log('格式化函数解释出错：', e);
    }
  } else {
    currValue.value = value;
  }
  await nextTick(() => initializing.value = false);
});

const getData = () => {
  return {
    inputParam: Object.assign({}, currNode.value.inputParam, props.inputParam),
    value: currValue.value
  };
};

const changeStyle = (styleId) => {
  init(styleId);
};

const currStyle = computed(() => {
  let style = visual.parseStyle(currNode.value.currStyle);
  const compStyle = currNode.value.currCompStyle || {};
  style += ';--vc-text-color: ' + (compStyle['fontColor'] || 'inherit') + ';';
  style += ';--vc-text-hover-color: ' + (compStyle['hover.fontColor'] || compStyle['fontColor'] || 'inherit') + ';';
  style += ';--vc-text-hover-underline: ' + (compStyle['hover.underline'] ? 'underline' : 'none') + ';';
  return style;
});

const style = computed(() => {
  const compStyle = currNode.value.currCompStyle || {};
  let style = visual.parseFontStyle(compStyle, {fontColor: ''});
  if (compStyle['align']) {
    style += `text-align: ${compStyle['align']};`;
  }
  if (compStyle['limitLine']) {
    style += 'display: -webkit-box;' +
      '-webkit-box-orient: vertical;' +
      `-webkit-line-clamp: ${compStyle['limitLine']};` +
      'overflow: hidden;';
  }
  return style;
});

const refresh = () => {
  loadValue();
};

onMounted(async() => {
  await init();
  loadValue();
  await eventHandler.trigger('初始化事件');
});

onUnmounted(() => {
  eventHandler.unregister();
});

defineExpose({ getData, changeStyle, refresh });
</script>

<style scoped lang="scss">
.vc-text {
  color: var(--vc-text-color);
}
.vc-text:hover {
  color: var(--vc-text-hover-color);
  text-decoration: var(--vc-text-hover-underline);
}
</style>